import { Op } from 'sequelize';
import Tenant from '@/models/Tenant.model';
import User from '@/models/User.model';
import Plan from '@/models/Plan.model';
import { TenantStatus, UserType, PaginatedResult } from '@/types';
import { getPaginationParams } from '@/utils/helpers';
import logger from '@/utils/logger';
import AuditLog from '@/models/AuditLog.model';
import { AuditAction } from '@/types';
import TenantPermissionService from './TenantPermissionService';

interface CreateTenantData {
  name: string;
  subdomain: string;
  planId: string;
  adminEmail: string;
  adminPassword: string;
  adminFirstName?: string;
  adminLastName?: string;
}

interface UpdateTenantData {
  name?: string;
  planId?: string;
  status?: TenantStatus;
  config?: Record<string, any>;
  trialEndsAt?: Date;
  subscriptionEndsAt?: Date;
}

interface ListTenantsFilter {
  status?: TenantStatus;
  planId?: string;
  search?: string;
  page?: number;
  pageSize?: number;
}

/**
 * 租户服务
 */
export class TenantService {
  /**
   * 创建租户
   */
  async createTenant(data: CreateTenantData, creatorId?: string): Promise<Tenant> {
    // 检查子域名是否已存在
    const existingTenant = await Tenant.findOne({
      where: { subdomain: data.subdomain },
    });

    if (existingTenant) {
      throw new Error('子域名已被使用');
    }

    // 检查套餐是否存在
    const plan = await Plan.findByPk(data.planId);
    if (!plan || !plan.isActive) {
      throw new Error('套餐不存在或已禁用');
    }

    // 检查管理员邮箱是否已存在
    const existingUser = await User.findOne({
      where: { email: data.adminEmail },
    });

    if (existingUser) {
      throw new Error('管理员邮箱已被使用');
    }

    // 创建租户
    const tenant = await Tenant.create({
      name: data.name,
      subdomain: data.subdomain,
      planId: data.planId,
      status: TenantStatus.TRIAL,
      trialEndsAt: new Date(Date.now() + 30 * 24 * 60 * 60 * 1000), // 30天试用
    });

    // 创建租户管理员
    await User.create({
      tenantId: tenant.id,
      email: data.adminEmail,
      password: data.adminPassword,
      firstName: data.adminFirstName,
      lastName: data.adminLastName,
      type: UserType.TENANT_ADMIN,
      status: 'active',
    });

    // 记录审计日志
    if (creatorId) {
      await AuditLog.create({
        tenantId: null,
        userId: creatorId,
        action: AuditAction.CREATE,
        resource: 'tenant',
        resourceId: tenant.id,
        changes: { name: data.name, subdomain: data.subdomain },
      });
    }

    // 同步套餐权限
    try {
      await TenantPermissionService.syncPlanPermissions(tenant.id);
      logger.info(`租户权限同步成功: ${tenant.subdomain} (${tenant.id})`);
    } catch (error) {
      logger.error(`租户权限同步失败: ${tenant.subdomain} (${tenant.id})`, error);
    }

    logger.info(`创建租户成功: ${tenant.subdomain} (${tenant.id})`);

    return tenant;
  }

  /**
   * 获取租户详情
   */
  async getTenantById(id: string): Promise<Tenant | null> {
    return Tenant.findByPk(id, {
      include: [
        {
          model: Plan,
          as: 'plan',
          attributes: ['id', 'name', 'code', 'description', 'price', 'billingCycleCode', 'priceMonthly', 'priceYearly', 'maxUsers', 'maxStorage', 'maxProjects', 'supportLevel'],
        },
      ],
    });
  }

  /**
   * 获取租户列表
   */
  async listTenants(filter: ListTenantsFilter): Promise<PaginatedResult<Tenant>> {
    const { page = 1, pageSize = 20, status, planId, search } = filter;
    const pagination = getPaginationParams(page, pageSize);

    const whereClause: any = {};

    if (status) {
      whereClause.status = status;
    }

    if (planId) {
      whereClause.planId = planId;
    }

    if (search) {
      whereClause[Op.or] = [
        { name: { [Op.iLike]: `%${search}%` } },
        { subdomain: { [Op.iLike]: `%${search}%` } },
      ];
    }

    const { count, rows } = await Tenant.findAndCountAll({
      where: whereClause,
      offset: pagination.offset,
      limit: pagination.limit,
      order: [['createdAt', 'DESC']],
      include: [
        {
          model: Plan,
          as: 'plan',
          attributes: ['id', 'name', 'code', 'description', 'price', 'billingCycleCode', 'priceMonthly', 'priceYearly', 'maxUsers', 'maxStorage', 'maxProjects', 'supportLevel'],
        },
      ],
    });

    return {
      data: rows,
      pagination: {
        total: count,
        page: pagination.page,
        pageSize: pagination.pageSize,
        totalPages: Math.ceil(count / pagination.pageSize),
      },
    };
  }

  /**
   * 更新租户
   */
  async updateTenant(
    id: string,
    data: UpdateTenantData,
    updaterId?: string,
  ): Promise<Tenant> {
    const tenant = await Tenant.findByPk(id);

    if (!tenant) {
      throw new Error('租户不存在');
    }

    // 如果更新套餐，检查套餐是否存在
    if (data.planId && data.planId !== tenant.planId) {
      const plan = await Plan.findByPk(data.planId);
      if (!plan || !plan.isActive) {
        throw new Error('套餐不存在或已禁用');
      }
    }

    const oldData = tenant.toJSON();
    const planChanged = data.planId && data.planId !== tenant.planId;
    
    await tenant.update(data);

    // 如果套餐变更，同步权限
    if (planChanged) {
      try {
        await TenantPermissionService.syncPlanPermissions(tenant.id);
        logger.info(`租户权限同步成功: ${tenant.subdomain} (${tenant.id})`);
      } catch (error) {
        logger.error(`租户权限同步失败: ${tenant.subdomain} (${tenant.id})`, error);
      }
    }

    // 记录审计日志
    if (updaterId) {
      await AuditLog.create({
        tenantId: null,
        userId: updaterId,
        action: AuditAction.UPDATE,
        resource: 'tenant',
        resourceId: tenant.id,
        changes: { before: oldData, after: data },
      });
    }

    logger.info(`更新租户: ${tenant.subdomain} (${tenant.id})`);

    return tenant;
  }

  /**
   * 激活租户
   */
  async activateTenant(id: string, updaterId?: string): Promise<Tenant> {
    return this.updateTenant(
      id,
      { status: TenantStatus.ACTIVE },
      updaterId,
    );
  }

  /**
   * 暂停租户
   */
  async suspendTenant(id: string, updaterId?: string): Promise<Tenant> {
    return this.updateTenant(
      id,
      { status: TenantStatus.SUSPENDED },
      updaterId,
    );
  }

  /**
   * 删除租户（软删除）
   */
  async deleteTenant(id: string, deleterId?: string): Promise<void> {
    const tenant = await Tenant.findByPk(id);

    if (!tenant) {
      throw new Error('租户不存在');
    }

    await tenant.destroy();

    // 记录审计日志
    if (deleterId) {
      await AuditLog.create({
        tenantId: null,
        userId: deleterId,
        action: AuditAction.DELETE,
        resource: 'tenant',
        resourceId: tenant.id,
      });
    }

    logger.info(`删除租户: ${tenant.subdomain} (${tenant.id})`);
  }

  /**
   * 获取租户统计信息
   */
  async getTenantStats(id: string) {
    const tenant = await Tenant.findByPk(id);

    if (!tenant) {
      throw new Error('租户不存在');
    }

    const userCount = await User.count({ where: { tenantId: id } });
    const activeUserCount = await User.count({
      where: { tenantId: id, status: 'active' },
    });

    return {
      userCount,
      activeUserCount,
      status: tenant.status,
      planId: tenant.planId,
      trialEndsAt: tenant.trialEndsAt,
      subscriptionEndsAt: tenant.subscriptionEndsAt,
    };
  }
}

export default new TenantService();

